package o2o.config.redis.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.jinyou.utils.common.ValidateUtil;
import lombok.extern.slf4j.Slf4j;
import o2o.config.redis.RedisManager;
import o2o.config.redis.basic.ListData;
import o2o.config.redis.basic.MapData;
import o2o.config.redis.basic.SingleData;
import o2o.config.redis.service.RedisCacheService;
import java.util.List;
import java.util.Map;
import java.util.Random;


/**
 * redis数据缓存服务
 * @author :ld
 * @date :2021/6/4
 */
@Slf4j
public class RedisCacheServiceImpl implements RedisCacheService {

    @Override
    public Integer randomTime() {
        int max = 3600;
        int min = 1800;
        Random random = new Random();
        return random.nextInt(max)%(max-min+1) + min;
    }

    @Override
    public <T> T addSingleCache(T t, String key) {
        return addSingleCache(t,key,null);
    }

    @Override
    public <T> T addSingleCache(T t, String key, Long seconds) {
        try {
            RedisManager.set(key,t,seconds==null? randomTime():seconds);
            return t;
        } catch (Exception e) {
            log.info("对象缓添加失败，原因：{}",e.getMessage());
            return null;
        }
    }

    @Override
    public <T> T singleCache(SingleData<T> singleData, String key) {
        return singleCache(singleData,key,null);
    }

    @Override
    public <T> T singleCache(SingleData<T> singleData, String key, Long seconds) {
        //从缓存中获取对象
        T t = JSON.parseObject(JSON.toJSONString(RedisManager.get(key)),new TypeReference<T>(){});
        //如果缓存对象为空
        if (t == null){
            //查询数据库
            T data = singleData.getData();
            if (data != null){
                //更新缓存
                addSingleCache(data,key,seconds);
            }
            log.info("从数据库中获取数据=>{}",JSON.toJSONString(data));
            return data;
        }
        log.info("从缓存中获取数据=>{}",JSON.toJSONString(t));
        return t;
    }

    @Override
    public Boolean delSingleCache(String key) {
        try {
            RedisManager.del(key);
            return true;
        } catch (Exception e) {
            log.info("缓存删除失败，原因：{}",e.getMessage());
            return false;
        }
    }

    @Override
    public <T> List<T> listCache(ListData<T> listData, String key,Class<T> tClass) {
        return listCache(listData,key,null,tClass);
    }

    @Override
    public <T> List<T> listCache(ListData<T> listData, String key, Long seconds,Class<T> tClass) {
        //从缓存中获取对象
        List<T> list = JSON.parseArray(JSON.toJSONString(RedisManager.lGet(key,0,-1)),tClass);
        //如果缓存对象为空
        if (!ValidateUtil.isAbsList(list)){
            //查询数据库
            List<T> data = listData.getData();
            if (data != null){
                //更新缓存
                for (T t : data) {
                    RedisManager.lSet(key, t, seconds == null?randomTime():seconds);
                }
            }
            log.info("从数据库中获取数据=>{}",JSON.toJSONString(data));
            return data;
        }
        log.info("从缓存中获取数据=>{}",JSON.toJSONString(list));
        return list;
    }

    @Override
    public Boolean delListCache(String key) {
        try {
            RedisManager.del(key);
            return true;
        } catch (Exception e) {
            log.info("缓存删除失败，原因：{}",e.getMessage());
            return false;
        }
    }

    @Override
    public <K, V> Map<K, V> mapCache(MapData<K, V> mapData, String key) {
        return mapCache(mapData,key,null);
    }

    @Override
    public <K, V> Map<K, V> mapCache(MapData<K, V> mapData, String key, Long seconds) {
        //从缓存中获取对象
        Map<K,V> map = JSON.parseObject(JSON.toJSONString(RedisManager.hmget(key)),new TypeReference<Map<K,V>>(){});
        //如果缓存对象为空
        if (!ValidateUtil.isAbsMap(map)){
            //查询数据库
            Map<K,V> data = mapData.getData();
            if (data != null){
                //更新缓存
                RedisManager.hmset(key, data,seconds == null?randomTime():seconds);
            }
            log.info("从数据库中获取数据=>{}",JSON.toJSONString(data));
            return data;
        }
        log.info("从缓存中获取数据=>{}",JSON.toJSONString(map));
        return map;
    }

    @Override
    public Boolean delMapCache(String key) {
        try {
            RedisManager.del(key);
            return true;
        } catch (Exception e) {
            log.info("缓存删除失败，原因：{}",e.getMessage());
            return false;
        }
    }
}
